package com.simpleplayer.services;

import android.os.Handler;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

//使用jsoup库解析html网页
public class JsoupHTMLResourceExtractor extends HTMLResourceExtractor {

    private static final String TAG = "JsoupHTMLResourceExtractor";

    private static final String EXTRACT_THREAD_NAME = "jsoup-thread";

    private final Handler mMainHandler;

    public JsoupHTMLResourceExtractor() {
        mMainHandler = new Handler();
    }

    public void extract(@NonNull String url, Listener listener) {
        // 启动一个子线程请求网页 html 内容
        new Thread(() -> {
            LogUtil.i(TAG, "开始连接网页：" + url);
            Document document = null;
            try {
                document = Jsoup.connect(url).get();
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                LogUtil.i(TAG, "结束与网页" + url + "的连接");
                Document finalDocument = document;
                mMainHandler.post(()-> {
                    onGetURLSource(finalDocument, listener);
                });
            }
        }, EXTRACT_THREAD_NAME).start();
    }

    private void onGetURLSource(Document document, Listener listener) {
        if (document == null) {
            listener.onExtractFinish(this, null);
        } else {
            LogUtil.i(TAG, "开始分析网页内容");

            ArrayList<VideoInfo> videoInfos = extractVideoTags(document);
            ArrayList<LinkInfo> linkInfos = extractATags(document);
            if (linkInfos != null) {
                if (videoInfos == null) {
                    videoInfos = new ArrayList<VideoInfo>();
                }
                extraVideoByLink(linkInfos, videoInfos);
            }

            WebContents webContent = new WebContents();
            webContent.appendUri(document.location());
            webContent.appendContent(document.outerHtml());
            webContent.appendVideoInfos(videoInfos);
            webContent.appendLinkInfos(linkInfos);
            LogUtil.i(TAG, "结束分析网页内容");
            listener.onExtractFinish(this, webContent);
        }
    }

    private ArrayList<VideoInfo> extractVideoTags(Document document) {
        Elements videos = document.getElementsByTag("video");
        if (videos == null || videos.isEmpty()) return null;

        ArrayList<VideoInfo> videoInfos = new ArrayList<>();
        for (Element video: videos) {
            VideoInfo videoInfo = parseVideoTag(video);
            if (videoInfo != null) {
                videoInfos.add(videoInfo);
            }
        }

        return videoInfos;
    }

    private VideoInfo parseVideoTag(Element video) {
        try {
            VideoInfo videoInfo = new VideoInfo();
            ArrayList<String> videoSources = new ArrayList<>();
            String relativeUri = video.attributes().get("src");

            if (relativeUri == null || relativeUri.isEmpty()) return null;
            String completeUrl = new URL(new URL(video.baseUri()), relativeUri).toString();
            videoSources.add(completeUrl);

            String poster = video.attributes().get("poster");
            if (poster != null && !poster.isEmpty()) {
                videoInfo.poster = new URL(new URL(video.baseUri()), poster).toString();
            }

            videoInfo.sources = videoSources;
            videoInfo.title = video.attributes().get("title");

            return videoInfo;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }

    private ArrayList<LinkInfo> extractATags(Document document) {
        Elements links = document.getElementsByTag("a");
        if (links == null || links.isEmpty()) return null;

        ArrayList<LinkInfo> linkInfos = new ArrayList<>();
        for (Element link: links) {
            LinkInfo linkInfo = parseATag(link);
            if (linkInfo != null) {
                linkInfos.add(linkInfo);
            }
        }

        return linkInfos;
    }

    private LinkInfo parseATag(Element link) {
        try {
            LinkInfo linkInfo = new LinkInfo();
            String relativeUri = link.attributes().get("href");

            if (relativeUri == null || relativeUri.isEmpty()) return null;
            linkInfo.href = new URL(new URL(link.baseUri()), relativeUri).toString();
            linkInfo.type = UriUtil.getMimeType(linkInfo.href);

            return linkInfo;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }

    private void extraVideoByLink(ArrayList<LinkInfo> linkInfos, ArrayList<VideoInfo> videoInfos) {
        for (LinkInfo linkInfo: linkInfos) {
            if (!TextUtils.isEmpty(linkInfo.type) && linkInfo.type.startsWith("video/")) {
                // 将超链接信息封装成视频信息添加到videoInfos中
                VideoInfo videoInfo = new VideoInfo();
                ArrayList<String> videoSources = new ArrayList<>();
                videoSources.add(linkInfo.href);
                videoInfo.sources = videoSources;
                videoInfos.add(videoInfo);
            }
        }
    }
}
